package com.chujian.framework.echo;

import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chujian.framework.annotation.echo.UseEcho;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 回显数据收集器
 *
 * @author chujian
 * @since 2022-03-08 10:06
 **/
public class EchoDataCollector {

    private final Object result;
    private final UseEcho useEcho;

    // 收集到的数据放在这个集合中
    private final List<Object> collector = new ArrayList<>();

    public EchoDataCollector(Object result, UseEcho useEcho) {
        this.result = result;
        this.useEcho = useEcho;
    }

    /**
     * 收集待回显的数据
     *
     * @return
     */
    public List<?> collectData() {
        if (result instanceof IPage) { // Ipage
            List<?> records = ((IPage<?>) result).getRecords();
            collector.addAll(records);

        } else if (result instanceof List) { // list
            collector.addAll((List<?>) result);

        } else { // 单值
            collector.add(result);
        }

        // 树结构数据收集
        collectTreeData();

        return collector;
    }

    /**
     * 收集指定字段id
     *
     * @param field
     * @return
     */
    public List<Serializable> collectIds(Field field) {
        List<Serializable> fieldIds = collector.stream()
                .filter(Objects::nonNull)
                // 获取ID
                .map(item -> ((Serializable) ReflectUtil.getFieldValue(item, field)))
                // 非空
                .filter(Objects::nonNull)
                // 去重
                .distinct()
                .collect(Collectors.toList());
        return fieldIds;
    }

    /**
     * 获取实体类
     *
     * @return
     */
    public Class<?> getEntityClass() {
        return collector.get(0).getClass();
    }


    /**
     * 收集树结构的数据
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    private void collectTreeData() {
        if (useEcho.isTree()) {
            List collectDataList = new ArrayList<>();
            for (Object item : collector) {
                recursionCollectTreeData(collectDataList, item);
            }
            collector.addAll(collectDataList);
        }
    }

    /**
     * 递归收据需要回显的数据
     *
     * @param collectDataList 存储收集的结果
     * @param data            data
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    private void recursionCollectTreeData(List collectDataList, Object data) {
        if (null == data) return;
        Object value = ReflectUtil.getFieldValue(data, useEcho.childrenField());
        if (value instanceof Collection) {
            Collection<?> childrenList = (Collection<?>) value;
            collectDataList.addAll(childrenList);
            for (Object item : childrenList) {
                recursionCollectTreeData(collectDataList, item);
            }
        }
    }


}
